# 数据集模块
from sklearn.datasets import load_breast_cancer


from sklearn.linear_model import LogisticRegression
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import  Axes3D

from sklearn.preprocessing import StandardScaler


# 加载胸部癌症数据集
data = load_breast_cancer()
print(data)
# X取data中前两维的数据，y取目标值
X,y = data['data'][:,:2] , data['target']

# 对X归一化处理
scale = StandardScaler()
scale.fit(X)
X = scale.transform(X)
# 求出两个维度对应的数据在逻辑回归算法下的最优解
lr = LogisticRegression(fit_intercept=False)
lr.fit(X,y)
# 分别把两个维度所对应的参数w1,w2取出来
theta1 = lr.coef_[0,0]
theta2 = lr.coef_[0,1]
print(f"theta1:{theta1},theta2:{theta2}")
# sigmoid function 已知w1和w2的情况下，传进来数据x，返回数据的y_predict
def p_theta_function(features,w1,w2):
    z = w1*features[0] + w2*features[1]
    return 1/(1+np.exp(-z))

# logistic loss function 传入一份已知数据的x,y，如果已知w1和w2的情况下，计算对应这份数据的loss损失
def loss_function(sample_features,sample_labels,w1,w2):
    result = 0
    # 遍历数据集中的每一条样本，并且计算每条样本的损失，加到result身上，得到整体的数据集损失
    for features,labels in zip(sample_features,sample_labels):
        # 这是计算一条样本的y_predict
        p_result = p_theta_function(features,w1,w2)
        loss_result = -1*labels*np.log(p_result)-(1-labels)*np.log(1-p_result)
        result +=loss_result
    return result
# 设置图像w1,w2轴
theta1_space = np.linspace(theta1-0.6,theta1+0.6,50)
theta2_space = np.linspace(theta2-0.6,theta2+0.6,50)
# result1_是最优化w2后，改变w1的值来观测loss值的变化
result1_ = np.array([loss_function(X,y,i,theta2) for i in theta1_space])
# result2_是最优化w1后，改变w2的值来观测loss值的变化
result2_ = np.array([loss_function(X,y,theta1,i) for i in theta2_space])

fig1 = plt.figure(figsize=(8,6))
# 两行两列的画布
plt.subplot(2,2,1)
plt.plot(theta1_space,result1_)

plt.subplot(2,2,2)
plt.plot(theta2_space,result2_)
# 绘制等高线
plt.subplot(2,2,3)
theta1_grid,theta2_grid = np.meshgrid(theta1_space, theta2_space)
loss_grid=loss_function(X,y,theta1_grid,theta2_grid)
plt.contour(theta1_grid,theta2_grid,loss_grid)

plt.subplot(2,2,4)
plt.contour(theta1_grid,theta2_grid,loss_grid,30)

fig2 = plt.figure(figsize=(8,6))
ax = Axes3D(fig2)
ax.plot_surface(theta1_grid,theta2_grid,loss_grid)

plt.show()

